package com.riversoft.weixin.common;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisAccessTokenHolder extends AccessTokenHolder {

    private static Logger logger = LoggerFactory.getLogger(JedisAccessTokenHolder.class);

    private static final String REDIS_CONFIG_PROP = "redis.properties";

    private Properties redisProp;

    private JedisPool pool;

    private AccessToken token;

    private static final String WP_EXPIEE_PREFIX = "WP_ExpireKey_";

    private String key;

    public JedisAccessTokenHolder(String tokenUrl, String clientId, String clientSecret) {
        super(tokenUrl, clientId, clientSecret);
        key = WP_EXPIEE_PREFIX + clientId;
        initJedisPool();
    }

    private void initJedisPool() {
        InputStream inStream;
        try {
            inStream = getClass().getClassLoader().getResource(REDIS_CONFIG_PROP).openStream();
            redisProp = new Properties();
            redisProp.load(inStream);
        } catch (IOException ex) {
            logger.error("获取redis 配置文件出错",ex);
            throw new RuntimeException("获取redis 配置文件出错",ex);
        }
        JedisPoolConfig config = new JedisPoolConfig();
        pool = new JedisPool(config,redisProp.getProperty("redis.host"),Integer.valueOf(redisProp.getProperty("redis.port")));
    }

    @Override
    public synchronized AccessToken getAccessToken() {
        Jedis jedis = null;
        String tokenStr;
        jedis = pool.getResource();
        tokenStr = jedis.get(key);
        AccessToken accessToken = AccessToken.fromJson(tokenStr);
        if (tokenStr == null) {
            refreshToken();
            accessToken = token;
        }
        return accessToken;
    }

    @Override
    public synchronized void refreshToken() {
        Jedis jedis = null;
        expireToken();
        String content = fetchAccessToken();
        token = AccessToken.fromJson(content);
        jedis = pool.getResource();
        jedis.setex(key, 2 * 60 * 60 * 1000 - 10000, content);
    }

    @Override
    public void expireToken() {
        Jedis jedis = null;
        jedis = pool.getResource();
        jedis.del(key);
    }

}
